﻿using System.Globalization;
using System.Text;

namespace DACU.Tools.JavaScript
{
	internal class JavaScriptString
	{
		// Fields
		private int _index;
		private string _s;

		// Methods
		internal JavaScriptString(string s)
		{
			_s = s;
		}

		private static void AppendCharAsUnicode(StringBuilder builder, char c)
		{
			builder.Append(@"\u");
			builder.AppendFormat(CultureInfo.InvariantCulture, "{0:x4}", new object[] { (int)c });
		}

		internal string GetDebugString(string message)
		{
			return string.Concat(new object[] { message, " (", _index, "): ", _s });
		}

		internal char? GetNextNonEmptyChar()
		{
			while (_s.Length > _index)
			{
				char c = _s[_index++];
				if (!char.IsWhiteSpace(c))
					return c;
			}
			return null;
		}

		internal char? MoveNext()
		{
			return _s.Length > _index ? (char?) _s[_index++] : null;
		}

		internal string MoveNext(int count)
		{
			if (_s.Length >= (_index + count))
			{
				string str = _s.Substring(_index, count);
				_index += count;
				return str;
			}
			return null;
		}

		internal void MovePrev()
		{
			if (_index > 0)
				_index--;
		}

		internal void MovePrev(int count)
		{
			while ((_index > 0) && (count > 0))
			{
				_index--;
				count--;
			}
		}

		public static string QuoteString(string value)
		{
			StringBuilder builder = null;
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			int startIndex = 0;
			int count = 0;
			for (int i = 0; i < value.Length; i++)
			{
				char c = value[i];
				if ((((c == '\r') || (c == '\t')) || ((c == '"') || (c == '\''))) || ((((c == '<') || (c == '>')) || ((c == '\\') || (c == '\n'))) || (((c == '\b') || (c == '\f')) || (c < ' '))))
				{
					if (builder == null)
						builder = new StringBuilder(value.Length + 5);
					if (count > 0)
						builder.Append(value, startIndex, count);
					startIndex = i + 1;
					count = 0;
				}
				switch (c)
				{
					case '<':
					case '>':
					case '\'':
						{
							AppendCharAsUnicode(builder, c);
							continue;
						}
					case '\\':
						{
							builder.Append(@"\\");
							continue;
						}
					case '\b':
						{
							builder.Append(@"\b");
							continue;
						}
					case '\t':
						{
							builder.Append(@"\t");
							continue;
						}
					case '\n':
						{
							builder.Append(@"\n");
							continue;
						}
					case '\f':
						{
							builder.Append(@"\f");
							continue;
						}
					case '\r':
						{
							builder.Append(@"\r");
							continue;
						}
					case '"':
						{
							builder.Append("\\\"");
							continue;
						}
				}
				if (c < ' ')
					AppendCharAsUnicode(builder, c);
				else
					count++;
			}
			if (builder == null)
				return value;
			if (count > 0)
				builder.Append(value, startIndex, count);
			return builder.ToString();
		}

		internal static string QuoteString(string value, bool addQuotes)
		{
			string str = QuoteString(value);
			if (addQuotes)
				str = @"""{0}""".FormatStr(str);
			return str;
		}

		public override string ToString()
		{
			return _s.Length > _index ? _s.Substring(_index) : string.Empty;
		}
	}
}
